package cn.lds.j368.dsbank.controller;

import cn.lds.j368.dsbank.annotation.SysLogAnnotation;
import cn.lds.j368.dsbank.constant.DsBankConstants;
import cn.lds.j368.dsbank.domain.*;
import cn.lds.j368.dsbank.dto.RespDTO;
import cn.lds.j368.dsbank.exception.ServiceException;
import cn.lds.j368.dsbank.exception.ValidatorException;
import cn.lds.j368.dsbank.service.CustomerService;

import cn.lds.j368.dsbank.service.DataDictionaryService;
import cn.lds.j368.dsbank.service.ProvinceCityDistrictService;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;


import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.Buffer;
import java.util.List;
import java.util.Objects;

@Controller
@RequestMapping("/customer")
public class CustomerController {

    @Autowired
    private CustomerService customerService;

    @Autowired
    private DataDictionaryService dataDictionaryService;

    @Autowired
    private ProvinceCityDistrictService provinceCityDistrictService;

    @Autowired
    private FastFileStorageClient fastFileStorageClient;


    private Logger log = LoggerFactory.getLogger(CustomerController.class);


    /**
     * 根据登录用户查询该用户添加的客户信息
     * @param model
     * @return
     */
    @GetMapping("show_customer")
    @SysLogAnnotation(operUrl = "/customer/show_customer",operModul = "/customer",operType = "查询",operDesc = "查询全部客户")
    public String showCustomerList(Model model){

        RespDTO<List<Customer>> listRespDTO = null;

        try {
            listRespDTO = customerService.selectCustomerAllByCreateEmpId(1);
            model.addAttribute("result",listRespDTO);
        } catch (ServiceException e) {
            throw new RuntimeException(e);
        }
        return "customer/show_customer";
    }

    /**
     * 根据客户id查询客户信息
     * @param customerId
     * @param model
     * @return
     */
    @GetMapping("show_details")
    @SysLogAnnotation(operUrl = "/customer/show_details",operModul = "/customer",operType = "查询",operDesc = "查询客户详情")
    public String showCustomerDetails(@RequestParam Long customerId,Model model){

        RespDTO<Customer> customerRespDTO = null;

        try {
            customerRespDTO = customerService.selectCustomerByCustomerId(customerId);
            model.addAttribute("result",customerRespDTO);
        } catch (ServiceException e) {
            throw new RuntimeException(e);
        }

        return "customer/show_details";

    }

    /**
     * 根据证件号码查询客户
     */
    @ResponseBody
    @GetMapping("query_cert_no")
    @SysLogAnnotation(operUrl = "/customer/query_cert_no",operModul = "/customer",operType = "查询",operDesc = "根据证件号码查询客户")
    public RespDTO<Customer> showCustomerByCertificateNo(String certifino){
        RespDTO<Customer> customerRespDTO = customerService.selectCustomerByCertificateNo(certifino);
        return customerRespDTO;
    }

    /**
     * 跳转到添加客户页面
     * @return
     */
    @GetMapping("add_customer")
    @SysLogAnnotation(operUrl = "/customer/add_customer",operModul = "/customer",operType = "添加",operDesc = "打开添加客户页面")
    public String addCustomer(Model model, HttpSession session){

        //通过数据字典查询客户身份类型信息
        List<DataDictionary> customerTypes = dataDictionaryService.selectDataByTypeCode("CUSTOMER_TYPE");
        List<DataDictionary> certificateTypes = dataDictionaryService.selectDataByTypeCode("CERTIFICATE_TYPE");
        //通过数组字典查询学历相关数据
        List<DataDictionary> educationStatus = dataDictionaryService.selectDataByTypeCode("EDUCATION_STATUS");
        //获取所有省份
        List<ProvinceCityDistrict> provinceCityDistricts = provinceCityDistrictService.selectPCDAllByPid(0);
        customerTypes.forEach(customerType -> log.info("客户身份类型:{}",customerType));


        model.addAttribute("customerTypes",customerTypes);
        model.addAttribute("certificateTypes",certificateTypes);
        model.addAttribute("educationStatus",educationStatus);
        model.addAttribute("provinces",provinceCityDistricts);


        return "customer/add_customer";
    }

    @PostMapping("/do_add_customer")
    @SysLogAnnotation(operUrl = "/customer/do_query_cert_no",operModul = "/customer",operType = "添加",operDesc = "体检客户信息")
    public String doAddCustomer(@Validated Customer customer, @Valid @NotBlank(message = "没有上传身份照片") MultipartFile certificateFileImgUrl, @AuthenticationPrincipal Employee employee, HttpServletRequest request, BindingResult errors) throws ValidatorException, ServiceException, IOException {
        log.info("添加客户数据：{}",customer);
        log.info("证件照片url{}",certificateFileImgUrl.getOriginalFilename());

        //获取上传文件的文件名
        String originalFilename = certificateFileImgUrl.getOriginalFilename();
        //获取上传文件的文件格式的mine
        String contentType = certificateFileImgUrl.getContentType();
        //如果文件格式不符合我们规定的文件格式，抛出异常
        if (!DsBankConstants.upload.CONTENT_TYPES.contains(contentType)){
            throw new ServiceException("上传文件格式不合法");
        }

        //如果上传文件为空
        try {
            BufferedImage image = ImageIO.read(certificateFileImgUrl.getInputStream());
            if (Objects.isNull(image)){
                throw new ServiceException("长传文件内容不合法");
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }



        //获取文件名的后缀名
        String ext = StringUtils.substringAfterLast(originalFilename, ".");

        //保存文件到服务器
        StorePath storePath = fastFileStorageClient.uploadFile(certificateFileImgUrl.getInputStream(), certificateFileImgUrl.getSize(), ext, null);
        //将上传文件的路径保存在customer对象中
        customer.setCertificateImgUrl("http://116.204.64.13/" + storePath.getFullPath());

//        String path = request.getServletContext().getRealPath("/certificateFileImgs");
        //我们默认创建员工id为1
        customer.setCreateEmpId(employee.getEmpId());

        if (errors.hasErrors()){
            //获取错误信息
            List<FieldError> fieldErrors = errors.getFieldErrors();
            for (FieldError fieldError : fieldErrors) {
                throw new ValidatorException(fieldError.getField() + fieldError.getDefaultMessage());
            }
        }


        customerService.addCustomer(customer);


        return "redirect:/customer/show_customer";
    }

    @GetMapping("/t_v")
    public String teatValidatorPage(){
        return "/customer/add_test";
    }

    /**
     * 测试JSR303 后端验证工具
     * @param person
     * @return
     */
    @ResponseBody
    @PostMapping("/test_validator")
    public String testValidator(Person person,MultipartFile ci, HttpServletRequest request) throws ValidatorException, IOException {

//
        //获取文件上传路径
        String path = request.getServletContext().getRealPath("/cis");

        //查看是否有该路径，如果没有，创建该文件夹
        File file = new File(path);

        if (!file.exists()){
            file.mkdir();
        }
//

        log.info("上传文件名:{}",ci.getOriginalFilename());
        log.info("上传文件的文件格式：{}",ci.getContentType());
        log.info("person:{}",person);

        ci.transferTo(new File(path,ci.getOriginalFilename()));

        log.info("上传后的路径：http://localhost:8080/cis/" + ci.getOriginalFilename());


        return "上传后的路径：http://localhost:8080/cis/" + ci.getOriginalFilename();
    }

    @GetMapping("/remove_customer/{customerId}")
    @SysLogAnnotation(operUrl = "/customer/revove_customer",operModul = "/customer",operType = "删除",operDesc = "删除客户")
    public String removeCustomer(@PathVariable Integer customerId) throws ServiceException {

        RespDTO respDTO = customerService.delCustomerByCustomerId(customerId);
        return "forward:/customer/show_customer";
    }


}
